﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SGS.Standard.EventArgs;
using SGS.Cards;
using SGS.Standard.Actor;

namespace SGS.Standard.GameLogic
{
    internal class PlayerTurn : GameLogicBase
    {
        #region 玩家回合阶段
        internal static void GL_PlayerTurn(Player currentPlayer)
        {
            // TODO 处理翻面
            RaiseNoticeMessageEvent("{0} 的回合", currentPlayer.PlayerName);

            PlayerTurnEventArgs e = new PlayerTurnEventArgs(GameContext.Current, currentPlayer);

            GL_PlayerBeginStage(e);
            GL_PlayerJudgeStage(e);
            GL_PlayerGetCardFromHeapStage(e);
            GL_PlayerHumanActorStage(e);
            GL_PlayerDiscardStage(e);
            GL_PlayerEndStage(e);
            // TODO: 触发“放权”，“连破”
        }

        internal static void GL_PlayerBeginStage(PlayerTurnEventArgs e)
        {
            if (!e.CurrentPlayer.GameInfo.Live)
            {
                return;
            }

            if (!e.BeginStageCompleted)
            {
                e.BeginStageCompleted = true;
            }
        }

        internal static void GL_PlayerJudgeStage(PlayerTurnEventArgs e)
        {
            if (!e.CurrentPlayer.GameInfo.Live)
            {
                return;
            }

            if (!e.JudgeStageCompleted)
            {
                if (e.CurrentPlayer.GameInfo.JudgeArea.Count > 0)
                {
                    RaiseNoticeMessageEvent("{0} 判定阶段", e.CurrentPlayer.PlayerName);

                    while (e.CurrentPlayer.GameInfo.JudgeArea.Count > 0)
                    {
                        var skill = e.CurrentPlayer.GameInfo.JudgeArea.Pop();
                        switch (skill.AsSkillType)
                        {
                            case CardType.LeBuSiShu:
                                Core.GL_Judge(e.CurrentPlayer, (player, judgeCard) =>
                                {
                                    // RaiseNoticeMessageEvent( "{0}的乐不思蜀判定牌为{2}", player.PlayerName, skill.AsSkillType, judgeCard.ToString());
                                    if (judgeCard.Suit == Suit.Heart)
                                    {
                                        RaiseNoticeMessageEvent("{0} 的乐不思蜀失效", player.PlayerName);
                                    }
                                    else
                                    {
                                        RaiseNoticeMessageEvent("{0} 的乐不思蜀生效，跳过出牌阶段", player.PlayerName);
                                        e.HumanActorStageCompleted = true;
                                    }
                                }, NameMapping.Parse(skill.AsSkillType));
                                break;
                            case CardType.BingLiangCunDuan:
                                Core.GL_Judge(e.CurrentPlayer, (player, judgeCard) =>
                                {
                                    // RaiseNoticeMessageEvent( "{0}的兵粮寸断判定牌为{2}", player.PlayerName, skill.AsSkillType, judgeCard.ToString());
                                    if (judgeCard.Suit == Suit.Club)
                                    {
                                        RaiseNoticeMessageEvent("{0} 的兵粮寸断失效", player.PlayerName);
                                    }
                                    else
                                    {
                                        RaiseNoticeMessageEvent("{0} 的兵粮寸断生效，跳过摸牌阶段", player.PlayerName);
                                        e.GetCardFromPoolStageCompleted = true;
                                    }
                                }, NameMapping.Parse(skill.AsSkillType));
                                break;
                            case CardType.ShanDian:
                                Core.GL_Judge(e.CurrentPlayer, (player, judgeCard) =>
                                {
                                    // RaiseNoticeMessageEvent( "{0}的闪电判定牌为{2}", player.PlayerName, skill.AsSkillType, judgeCard.ToString());
                                    if (judgeCard.Suit == Suit.Spade && judgeCard.Point >= 2 && judgeCard.Point <= 9)
                                    {
                                        RaiseNoticeMessageEvent("{0} 的闪电生效，遭遇天谴", player.PlayerName, skill.AsSkillType);
                                        Core.GL_Damage(null, e.CurrentPlayer, DamageType.Thunder, skill.UsedCards, 3);
                                    }
                                    else
                                    {
                                        RaiseNoticeMessageEvent("{0} 的闪电失效", player.PlayerName, skill.AsSkillType);

                                        var nextPlayer = GamePool.Current.PlayersCircle.GetCircleNode(e.CurrentPlayer).Next;
                                        while (true)
                                        {
                                            if (nextPlayer.Value.GameInfo.JudgeArea.Where(x => x.AsSkillType == CardType.ShanDian).Count() == 0)
                                            {
                                                nextPlayer.Value.GameInfo.JudgeArea.Push(skill);
                                                RaiseNoticeMessageEvent("{0} 的闪电传递给了{1}", player.PlayerName, nextPlayer.Value.PlayerName);
                                                break;
                                            }
                                            else
                                            {
                                                nextPlayer = nextPlayer.Next;
                                            }
                                        }
                                    }
                                }, NameMapping.Parse(skill.AsSkillType));
                                break;
                            default:
                                break;
                        }
                    }
                }

                e.JudgeStageCompleted = true;
            }
        }

        internal static void GL_PlayerGetCardFromHeapStage(PlayerTurnEventArgs e)
        {
            if (!e.CurrentPlayer.GameInfo.Live)
            {
                return;
            }

            if (!e.GetCardFromPoolStageCompleted)
            {
                Core.PlayerDealCards(e.CurrentPlayer, 2);

                e.GetCardFromPoolStageCompleted = true;
            }
        }

        internal static void GL_PlayerHumanActorStage(PlayerTurnEventArgs e)
        {
            if (!e.CurrentPlayer.GameInfo.Live)
            {
                return;
            }

            if (!e.HumanActorStageCompleted)
            {
                HumanActorEventArgs eq = new HumanActorEventArgs(e.GameContext, e.CurrentPlayer, null);
                HumanAnswerActorEventArgs ea = new HumanAnswerActorEventArgs(e.GameContext);

                RaiseNoticeMessageEvent("{0} 出牌阶段", e.CurrentPlayer.PlayerName);

                while (ea.AnswerActor == null)
                {
                    if (!e.CurrentPlayer.GameInfo.Live)
                    {
                        return;
                    }

                    RaiseHumanActorEvent(eq, ea);

                    if (ea.AnswerActor is CancelActor || ea.AnswerActor is SkipActor)
                    {
                        break;
                    }
                    else if (ea.AnswerActor is SGS.Standard.Actor.HumanAnswerActor.UseCardActor)
                    {
                        var answer = ea.AnswerActor as SGS.Standard.Actor.HumanAnswerActor.UseCardActor;

                        switch (answer.AsSkillType)
                        {
                            case CardType.Bang:
                            case CardType.FireBang:
                            case CardType.ThunderBang:
                                SGS.Standard.GameLogic.Basic.GL_Bang(ea.AnswerActor, eq.AnswerPlayer, answer.TargetFirst, answer.UsedCards);
                                break;
                            case CardType.Peach:
                                SGS.Standard.GameLogic.Basic.GL_Peach(eq.AnswerPlayer, eq.AnswerPlayer, answer.UsedCards);
                                break;
                            case CardType.LeBuSiShu:
                                SGS.Standard.GameLogic.Strategy.GL_LeBuSiShu(answer);
                                break;
                            case CardType.BingLiangCunDuan:
                                SGS.Standard.GameLogic.Strategy.GL_BingLiangCunDuan(answer);
                                break;
                            case CardType.ShanDian:
                                SGS.Standard.GameLogic.Strategy.GL_ShanDian(answer);
                                break;
                            case CardType.WanJianQiFa:
                                SGS.Standard.GameLogic.Strategy.GL_WanJianQiFa(answer);
                                break;
                            case CardType.TaoYuanJieYi:
                                SGS.Standard.GameLogic.Strategy.GL_TaoYuanJieYi(answer);
                                break;
                            case CardType.JueDou:
                                SGS.Standard.GameLogic.Strategy.GL_JueDou(answer);
                                break;
                            case CardType.GuoHeChaiQiao:
                                SGS.Standard.GameLogic.Strategy.GL_GuoHeChaiQiao(answer);
                                break;
                            case CardType.ShunShouQianYang:
                                SGS.Standard.GameLogic.Strategy.GL_ShunShouQianYang(answer);
                                break;
                            case CardType.WuZhongShengYou:
                                SGS.Standard.GameLogic.Strategy.GL_WuZhongShengYou(answer);
                                break;
                            case CardType.WuGuFengDeng:
                                SGS.Standard.GameLogic.Strategy.GL_WuGuFengDeng(answer);
                                break;
                            case CardType.JieDaoShaRen:
                                SGS.Standard.GameLogic.Strategy.GL_JieDaoShaRen(answer);
                                break;
                            case CardType.NanManRuQin:
                                SGS.Standard.GameLogic.Strategy.GL_NanManRuQin(answer);
                                break;
                            case CardType.Weapon:
                            case CardType.Armor:
                            case CardType.AttackHorse:
                            case CardType.DefenseHorse:
                                SGS.Standard.GameLogic.Basic.GL_Equip(answer.ActorPlayer, answer.AsSkillType, answer.UsedCards.FirstOrDefault());
                                break;
                            case CardType.Miss:
                            default:
                                // 无法直接打出闪
                                ea.AnswerActor = null;
                                break;
                        }
                    }
                    else if (ea.AnswerActor is SGS.Skills.SkillBase)
                    {
                        // TODO ： 发动技能处理部分
                    }

                    RaiseNoticeMessageEvent("Actor {0} Done", ea.AnswerActor == null ? "Unknown" : ea.AnswerActor.GetType().FullName);
                    ea.AnswerActor = null;
                }

                e.HumanActorStageCompleted = true;
            }
        }

        internal static void GL_PlayerDiscardStage(PlayerTurnEventArgs e)
        {
            try
            {
                if (!e.CurrentPlayer.GameInfo.Live)
                {
                    return;
                }

                if (!e.DiscardStageCompleted)
                {
                    int needDiscardCount = e.CurrentPlayer.GameInfo.OwnCards.Count - e.CurrentPlayer.GameInfo.CurrentHP;

                    if (needDiscardCount > 0)
                    {
                        RaiseNoticeMessageEvent("{0} 弃牌阶段: 需弃{1}张牌", e.CurrentPlayer.PlayerName, needDiscardCount);

                        HumanActorEventArgs eq = new HumanActorEventArgs(e.GameContext, e.CurrentPlayer, new SGS.Standard.Actor.DiscardStageActor(needDiscardCount));
                        HumanAnswerActorEventArgs ea = new HumanAnswerActorEventArgs(e.GameContext);

                        while (ea.AnswerActor == null)
                        {
                            RaiseHumanActorEvent(eq, ea);

                            if (ea.AnswerActor is SkipActor)
                            {
                                return;
                            }

                            if (ea.AnswerActor is CancelActor)
                            {
                                ea.AnswerActor = null;
                                continue;
                            }

                            if (ea.AnswerActor is DiscardStageHumanAnswerActor)
                            {
                                if (!ea.AnswerActor.CheckHumanActor(eq))
                                {
                                    ea.AnswerActor = null;
                                }
                            }
                        }

                        var actor = ea.AnswerActor as SGS.Standard.Actor.DiscardStageHumanAnswerActor;

                        e.CurrentPlayer.GameInfo.TryRemoveCard(actor.Discards);
                        Core.GL_Discard(e.CurrentPlayer, actor.Discards);
                    }
                }
            }
            catch
            {
            }
            finally
            {
                e.DiscardStageCompleted = true;
            }
        }

        internal static void GL_PlayerEndStage(PlayerTurnEventArgs e)
        {
            if (!e.CurrentPlayer.GameInfo.Live)
            {
                return;
            }

            if (!e.EndStageCompleted)
            {
                e.EndStageCompleted = true;
            }
        }

        #endregion
    }
}
